﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using SharpSvn;

namespace GestoreSuperProgetto.Model
{
    public partial class DbEntities
    {
        private USER _activeUser = null;
        public USER ActiveUser
        {
            get { return _activeUser; }
            set { _activeUser = value; }
        }
    }

    public partial class PROJECT
    {
        public override string ToString()
        {
            return this.NAME;
        }

        public override bool Equals(object obj)
        {
            if (obj is PROJECT)
                return this.ID.Equals((obj as PROJECT).ID);
            return base.Equals(obj);
        }
    }

    public partial class SUPERPROJECT
    {
        public override string ToString()
        {
            return this.NAME;
        }

        public override bool Equals(object obj)
        {
            if (obj is SUPERPROJECT)
                return this.ID.Equals((obj as SUPERPROJECT).ID);
            return base.Equals(obj);
        }
    }

    public enum TypePermission
    {
        Admin,
        Update,
        Commit
    }

    public partial class LABEL
    {
        protected override void OnPropertyChanged(string property)
        {
            if (property == "NAME")
            {
                if (this.NAME == "Sviluppo")
                    this.URL = "trunk";
                else
                    this.URL = "tags/" + this.NAME;
            }

            base.OnPropertyChanged(property);
        }

        public override string ToString()
        {
            return this.NAME;
        }
    }

    public partial class LABEL_PROJECTS
    {
        public void Load()
        {
            if (this.LABEL == null)
                this.LABELReference.Load();
            if (this.PROJECT == null)
                this.PROJECTReference.Load();
        }

        public string TagFullUrl
        {
            get {
                Load();
                if (this.LABEL.VERSION == 0)
                {
                    return string.Format("{0}{1}", this.PROJECT.URL, this.LABEL.URL).Replace("branches", "tags");
                }
                else if (this.LABEL.VERSION == 1)
                {
                    return string.Format("{0}{1}", this.PROJECT.URL, this.LABEL.URL);
                }

                return "";
            }
        }

        public string BranchFullUrl
        {
            get
            {
                Load();

                if (this.LABEL.VERSION == 0)
                {
                    return string.Format("{0}{1}", this.PROJECT.URL, this.LABEL.URL);
                }
                else if (this.LABEL.VERSION == 1)                
                {
                    if (this.LABEL.URL == "trunk")
                    {
                        return string.Format("{0}{1}", this.PROJECT.URL, this.LABEL.URL);
                    }
                    else
                    {
                        string labelName = this.LABEL.NAME;
                        string shortVer = labelName.Substring(labelName.IndexOf("_") + 1);
                        shortVer = shortVer.Substring(0, shortVer.LastIndexOf('.'));
                        return string.Format(@"{0}branches/Manut_{1}", this.PROJECT.URL, shortVer);
                    }
                }

                return "";
            }
        }

        public override string ToString()
        {
            Load();
            return this.PROJECT.NAME + " - " + this.LABEL.NAME;
        }

        public bool RemoveFromSvn(SharpSvn.SvnClient client)
        {
            bool retFunc = true;
            try
            {
                // 13/10/2011 Denis. Rimuovo il tags
                client.RemoteDelete(new Uri(this.TagFullUrl), new SvnDeleteArgs()
                {
                    LogMessage = "Delete " + this.PROJECT.NAME + " Label: " + this.LABEL.NAME + " tag"
                });

                var countExist = (from ele in this.PROJECT.LABEL_PROJECTS
                                  where ele.LABEL.NAME.StartsWith(this.LABEL.NAME.Substring(0, this.LABEL.NAME.LastIndexOf('.'))) &&
                                  ele.LABEL.NAME == this.LABEL.NAME
                                  select ele).Count();
                // Se non ci sono altre etichette di questo progetto per questa patch cancello anche la branch altrimenti la lascio
                if (countExist == 0)
                    // 13/10/2011 Denis. Rimuovo il branch
                    client.RemoteDelete(new Uri(this.BranchFullUrl), new SvnDeleteArgs()
                    {
                        LogMessage = "Delete " + this.PROJECT.NAME + " Label: " + this.LABEL.NAME + " branches"
                    });
            }
            catch
            {
                retFunc = false;
            }

            return retFunc;
        }
    }

    public partial class LABEL_SUPERPROJECTS
    {
        public void Load()
        {
            if (this.SUPERPROJECT == null)
                this.SUPERPROJECTReference.Load();
            if (this.LABEL == null)
                this.LABELReference.Load();
        }

        private long _currentLabelID = 0;

        [System.Runtime.Serialization.DataMemberAttribute()]
        public long CurrentLabelID
        {
            get { return _currentLabelID == 0 ? this.ID_LABEL : _currentLabelID; }
            set { _currentLabelID = value; }
        }

        public string SuperProjectName
        {
            get
            {
                Load();
                if (this.SUPERPROJECT!=null)
                    return this.SUPERPROJECT.NAME;
                return "";
            }
        }

        public string SuperProjectLabelName
        {
            get
            {
                Load();
                if(this.LABEL!=null)
                    return this.LABEL.NAME;
                return "";
            }
        }

        public override string ToString()
        {
            Load();
            return this.SuperProjectName + " - " + this.SuperProjectLabelName;
        }
    }

    public partial class SUPERPROJECTS_INSTALLED
    {
        public void Load()
        {            
            if (this.LABEL_SUPERPROJECTS == null)
                this.LABEL_SUPERPROJECTSReference.Load();
        }
        public string SuperProjectName
        {
            get
            {
                Load();
                return this.LABEL_SUPERPROJECTS.SuperProjectName;
            }
        }

        public string SuperProjectLabelName
        {
            get
            {
                Load();
                return this.LABEL_SUPERPROJECTS.SuperProjectLabelName;
            }
        }
    }

    public partial class USER
    {
        public override string ToString()
        {
            return this.USERNAME;
        }

        public override bool Equals(object obj)
        {
            if (obj is USER)
                return this.ID.Equals((obj as USER).ID);
            return base.Equals(obj);
        }

        public bool CheckPermission(long ID_SUPERPROJECT, TypePermission tPerm)
        {
            var perms = (from perm in this.PERMISSIONS
                         where perm.ID_SUPERPROJECT == ID_SUPERPROJECT
                         select perm).SingleOrDefault();

            bool ret = false;
            if (perms != null)
            {
                switch (tPerm)
                {
                    case TypePermission.Admin:
                        ret = (perms.PADMIN > 0);
                        break;
                    case TypePermission.Commit:
                        ret = (perms.PWRITE > 0);
                        break;
                    case TypePermission.Update:
                        ret = (perms.PREAD > 0);
                        break;
                }
            }
            return ret;
        }

        #region Static Functions

        private static string Salt = "Kosher";
        private static string HashAlgorithm = "SHA1";
        private static int PasswordIterations = 2;
        private static string InitialVector = "OFRna73m*aze01xY";
        private static int KeySize = 256;
        private static string Password = "QUESTOèPIPPOEPLUTOINSIEME";

        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="PlainText">Text to be encrypted</param>
        /// <param name="Password">Password to encrypt with</param>
        /// <param name="Salt">Salt to encrypt with</param>
        /// <param name="HashAlgorithm">Can be either SHA1 or MD5</param>
        /// <param name="PasswordIterations">Number of iterations to do</param>
        /// <param name="InitialVector">Needs to be 16 ASCII characters long</param>
        /// <param name="KeySize">Can be 128, 192, or 256</param>
        /// <returns>An encrypted string</returns>
        public static string Encrypt(string PlainText)
        {
            if (string.IsNullOrEmpty(PlainText))
                return "";
            byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
            byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);
            PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
            byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
            RijndaelManaged SymmetricKey = new RijndaelManaged();
            SymmetricKey.Mode = CipherMode.CBC;
            byte[] CipherTextBytes = null;
            using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
            {
                using (MemoryStream MemStream = new MemoryStream())
                {
                    using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                    {
                        CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                        CryptoStream.FlushFinalBlock();
                        CipherTextBytes = MemStream.ToArray();
                        MemStream.Close();
                        CryptoStream.Close();
                    }
                }
            }
            SymmetricKey.Clear();
            return Convert.ToBase64String(CipherTextBytes);
        }

        /// <summary>
        /// Decrypts a string
        /// </summary>
        /// <param name="CipherText">Text to be decrypted</param>
        /// <param name="Password">Password to decrypt with</param>
        /// <param name="Salt">Salt to decrypt with</param>
        /// <param name="HashAlgorithm">Can be either SHA1 or MD5</param>
        /// <param name="PasswordIterations">Number of iterations to do</param>
        /// <param name="InitialVector">Needs to be 16 ASCII characters long</param>
        /// <param name="KeySize">Can be 128, 192, or 256</param>
        /// <returns>A decrypted string</returns>
        public static string Decrypt(string CipherText)
        {
            if (string.IsNullOrEmpty(CipherText))
                return "";
            byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
            byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
            byte[] CipherTextBytes = Convert.FromBase64String(CipherText);
            PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
            byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
            RijndaelManaged SymmetricKey = new RijndaelManaged();
            SymmetricKey.Mode = CipherMode.CBC;
            byte[] PlainTextBytes = new byte[CipherTextBytes.Length];
            int ByteCount = 0;
            using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes))
            {
                using (MemoryStream MemStream = new MemoryStream(CipherTextBytes))
                {
                    using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read))
                    {

                        ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length);
                        MemStream.Close();
                        CryptoStream.Close();
                    }
                }
            }
            SymmetricKey.Clear();
            return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount);
        }

        #endregion
    }
}
